<template>
  <div ref="listSearchTable" class="list-search-table">
    <div ref="listSearchTableFilter" class="list-search-table-filter">
      <a-form :model="tableFilter.form">
        <a-row :gutter="24">
          <a-col :span="6">
            <a-form-item label="名称" v-bind="tableFilterValidateInfos.name">
              <a-input v-model:value="tableFilter.form.name" placeholder="请输入名称" />
            </a-form-item>
          </a-col>
          <a-col :span="6">
            <a-form-item label="领域" name="domain" v-bind="tableFilterValidateInfos.domain">
              <a-select v-model:value="tableFilter.form.domain" placeholder="请选择应用领域">
                <a-select-option value="">全部</a-select-option>
                <a-select-option v-for="(option, idx) in selectOptions.domain" :key="idx" :value="option.name">
                  {{ option.name }}
                </a-select-option>
              </a-select>
            </a-form-item>
          </a-col>
        </a-row>
      </a-form>
      <div style="height: 32px">
        <a-space>
          <a-button type="primary" @click.prevent="onOptionClick('create', null)">
            <template #icon>
              <plus-outlined />
            </template>
            新建
          </a-button>
          <!-- <a-button danger>
                <template #icon>
                  <DeleteOutlined />
                </template>
                删除
              </a-button> -->
        </a-space>
        <a-space style="float: right">
          <a-button type="primary" @click.prevent="onTableFilterSubmit">查询</a-button>
          <a-button @click="onTableFilterReset">重置</a-button>
        </a-space>
      </div>
    </div>
    <a-table
      :columns="table.columns"
      :data-source="table.data"
      bordered
      :pagination="false"
      :loading="loading"
      :scroll="tableScroll"
      @resize-column="(w, col) => (col.width = w)"
    >
      <template #bodyCell="{ column, record }">
        <template v-if="column.dataIndex === 'option'">
          <a-button size="small" type="link" @click="onOptionClick('detail', record)">详情</a-button>
          <a-dropdown>
            <a @click.prevent>
              更多
              <DownOutlined />
            </a>
            <template #overlay>
              <a-menu>
                <a-menu-item>
                  <a-button size="small" type="link" @click="onOptionClick('edit', record)">编辑</a-button>
                </a-menu-item>
                <a-menu-item>
                  <a-button size="small" type="link" @click="onOptionClick('enable', record)">
                    {{ record.enable ? '禁用' : '启用' }}
                  </a-button>
                </a-menu-item>
                <a-menu-item>
                  <a-button size="small" type="link" danger @click="onOptionClick('delete', record)">删除</a-button>
                </a-menu-item>
              </a-menu>
            </template>
          </a-dropdown>
        </template>
        <template v-if="column.dataIndex === 'icon'">
          <a-image
            :width="54"
            :height="54"
            :src="record.iconUrl"
            fallback=""
          />
        </template>

        <template v-if="column.dataIndex === 'enable'">
          <a-tag v-if="record.enable" color="success">正常</a-tag>
          <a-tag v-else color="error">关闭</a-tag>
        </template>
        <template v-if="column.dataIndex === 'lifeCycle'">
          {{
            selectOptions.lifeCycle
              ? selectOptions.lifeCycle.filter((item) => item.type === record.lifeCycle)[0].value
              : ''
          }}
        </template>
      </template>
    </a-table>
    <div ref="listSearchTablePagination" class="list-search-table-pagination">
      <a-pagination
        v-model:current="tablePagination.current"
        :total="tablePagination.total"
        @change="onTablePaginationChange"
      />
    </div>
  </div>
  <AppEditDrawer
    v-model:visible="editAppState.visible"
    v-model:loading="editAppState.loading"
    :title="editAppState.title"
    :current="editAppState.current"
    @submit="onEditAppSubmit"
  ></AppEditDrawer>
</template>

<script lang="ts" setup>
import {
  ref,
  Ref,
  reactive,
  onMounted,
  nextTick,
  computed,
  toRaw,
  defineEmits,
  createVNode,
  watch,
  provide,
  onBeforeMount,
  readonly,
} from 'vue'
import { useRouter } from 'vue-router'
import {
  PlusOutlined,
  DeleteOutlined,
  ExclamationCircleOutlined,
  DownOutlined,
  UpOutlined,
} from '@ant-design/icons-vue'
import { message, Form, Modal } from 'ant-design-vue'

import useLoading from '@/hooks/loading'
import {
  getAppList,
  getAppLifeCycleType,
  getAppDomainList,
  createApp,
  deleteApp,
  switchApp,
  updateApp,
} from '../factory'
import { appModel } from '../model'
import AppEditDrawer from '../components/AppEditDrawer.vue'

import { deepClone } from '@/utils/object'

const router = useRouter()

const { loading, loadingText, setLoading } = useLoading(true)
/****************************************
 *               表格样式                *
 ****************************************/

const inputWidth = '120px'
const listSearchTable: Ref = ref(null)
const listSearchTableFilter: Ref = ref(null)

const tableScroll = reactive<{ x?: number; y?: number }>({})
const onTableShowAdvanceFilter = () => {
  showAdvanceFilter.value = !showAdvanceFilter.value
  nextTick(() => {
    tableScroll.y = listSearchTable.value.clientHeight - listSearchTableFilter.value.clientHeight - 64 - 72
    console.log(tableScroll.y)
  })
}
nextTick(() => {
  tableScroll.y = listSearchTable.value.clientHeight - listSearchTableFilter.value.clientHeight - 64 - 72
  console.log(tableScroll.y)
})

const showAdvanceFilter = ref(false)
/****************************************
 *              表格筛选器                *
 ****************************************/
const tableFilter = reactive({
  form: {
    name: '',
    domain: '',
  },
  rules: {},
})

const selectOptions = reactive({
  domain: [] as any,
  lifeCycle: [] as any,
})

const {
  resetFields: onTableFilterReset,
  validate: onTableFilterValidate,
  validateInfos: tableFilterValidateInfos,
} = Form.useForm(tableFilter.form, tableFilter.rules, {
  onValidate: (...args) => console.log(...args),
})

const generateQuery = () => {
  let _queryForm = JSON.parse(JSON.stringify(toRaw(tableFilter.form)))

  return {
    ..._queryForm,
    pageNo: tablePagination.current,
    pageSize: tablePagination.pageSize,
  }
}

const onTableFilterSubmit = () => {
  onTableFilterValidate()
    .then(() => {
      tablePagination.current = 1
    })
    .then(() => fetchTableData())
    .catch((err) => {
      console.log('error', err)
    })
}

/****************************************
 *               表格主体                 *
 ****************************************/
const table = reactive({
  // 表格列
  columns: [
    {
      title: '操作',
      dataIndex: 'option',
      // resizable: true,
      width: 128,
      // minWidth: 100,
      // ellipsis: true,
      // fixed: "right",
    },
    {
      title: '图标',
      dataIndex: 'icon',
      resizable: true,
      width: 100,
      minWidth: 100,
      ellipsis: true,
      // fixed: "left",
    },
    {
      title: '名称',
      dataIndex: 'name',
      // resizable: true,
      // width: 100,
      // minWidth: 100,
      ellipsis: true,
      // fixed: "left",
    },
    {
      title: '领域',
      dataIndex: 'domain',
      resizable: true,
      width: 100,
      minWidth: 100,
      ellipsis: true,
    },
    {
      title: '启用状态',
      dataIndex: 'enable',
      resizable: true,
      width: 100,
      minWidth: 100,
      ellipsis: true,
      maxWidth: 200,
    },
    {
      title: '生命周期',
      dataIndex: 'lifeCycle',
      resizable: true,
      width: 100,
      minWidth: 100,
      ellipsis: true,
    },
    {
      title: '更新人',
      dataIndex: 'modifierName',
      resizable: true,
      width: 100,
      minWidth: 100,
      ellipsis: true,
    },
    {
      title: '更新时间',
      dataIndex: 'modifyTime',
      // resizable: true,
      // width: 100,
      // minWidth: 100,
      ellipsis: true,
    },
  ],
  // 表格数据
  data: [],
})

/****************************************
 *              表格分页器                *
 ****************************************/
const tablePagination = reactive({
  pageCount: 0,
  current: 1,
  pageSize: 10,
  total: 0,
})
const onTablePaginationChange = (current) => {
  // console.log(pagination)

  // const { current } = pagination
  tablePagination.current = current
  fetchTableData()
}

/****************************************
 *             表格请求数据               *
 ****************************************/
const fetchTableData = async () => {
  try {
    setLoading(true)
    const query = generateQuery()
    const res = await getAppList(query)
    const { dataList, pageCount, pageNo, pageSize, totalCount } = res.data

    table.data = dataList

    tablePagination.pageCount = pageCount
    tablePagination.total = Number(totalCount)
  } catch (error) {
    console.error(error)
  } finally {
    setLoading(false)
  }
}

/****************************************
 *               表格操作                 *
 ****************************************/
const onOptionClick = async (cmd, record) => {
  switch (cmd) {
    case 'create':
      editAppState.title = '新建应用'
      editAppState.visible = true
      break
    case 'detail': // 进入应用详情页
      router.push({ name: 'AppManageDetail', query: { appKey: record.appKey, appId: record.id } })
      break
    case 'edit': // 编辑应用
      editAppState.title = '编辑应用'
      editAppState.current = record
      editAppState.visible = true
      editAppState.loading = true
      break
    case 'delete': // 删除应用
      {
        Modal.confirm({
          title: '警告：删除操作不可逆！',
          icon: createVNode(ExclamationCircleOutlined),
          okText: '确认删除',
          okButtonProps: { danger: true },
          content: `该应用 [ ${record.name} ] 所有信息将被删除，请谨慎操作!`,
          onOk() {
            setLoading(true)
            return deleteApp(record.id)
              .then((res) => {
                if (res.success) {
                  message.success('操作成功')
                } else {
                  throw res.message
                }
              })
              .then(() => fetchTableData())
              .catch((error) => {
                console.error(error)
                message.error(error)
              })
              .finally(() => setLoading(false))
          },
        })
      }
      break
    case 'enable':
      {
        try {
          setLoading(true)
          const res = await switchApp(record.id, !record.enable)
          if (res.success) {
            message.success('操作成功')
            await fetchTableData()
          } else {
            throw res.message
          }
        } catch (error) {
          console.error(error)
          message.error(error as any)
        } finally {
          setLoading(false)
        }
      }
      break
    default:
      break
  }
}

/**
 * 生命周期 onMounted
 */
onMounted(async () => {
  await getAppDomainList().then((res) => {
    if (res.data && res.data.length > 0) {
      selectOptions.domain = res.data
    }
  })
  await getAppLifeCycleType().then((res) => {
    if (res.data && res.data.length > 0) {
      selectOptions.lifeCycle = res.data
    }
  })
  // 初始化请求数据
  await fetchTableData()
})
/*********************** 抽屉表单 **************************/
const editAppState = reactive({
  visible: false,
  title: '编辑应用',
  loading: false,
  current: deepClone(appModel),
})

watch(
  () => editAppState.visible,
  (visible) => {
    // 注意：`newValue` 此处和 `oldValue` 是相等的
    // *除非* state.someObject 被整个替换了
    if (!visible) {
      editAppState.current = deepClone(appModel)
    }
  },
  { immediate: true, deep: true }
)
const onEditAppSubmit = async (form) => {
  try {
    console.log(form)
    let _form = deepClone(form)

    editAppState.loading = true
    let res
    if (!_form.id) {
      res = await createApp(_form)
    } else {
      res = await updateApp(_form)
    }
    if (res.success) {
      message.success('操作成功')
      editAppState.visible = false
      await fetchTableData()
    } else {
      throw res.message
    }
  } catch (error) {
    console.error(error)
    message.error(error as any)
  } finally {
    editAppState.loading = false
  }
}
</script>

<style lang="less" scoped></style>
